home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / util / misc / MUser17src.lha / MultiUser / src / Library / Log.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-07  |  11.9 KB  |  502 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Login Access Management                                                *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993-1994 Geert Uytterhoeven                        *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/dos.h>
  13. #include <proto/utility.h>
  14. #include <proto/reqtools.h>
  15. #include <exec/execbase.h>
  16. #include <exec/alerts.h>
  17. #include <dos/dos.h>
  18. #include <dos/var.h>
  19. #include <dos/datetime.h>
  20. #include <utility/tagitem.h>
  21. #include <libraries/reqtools.h>
  22. #include <string.h>
  23.  
  24. #include "Log.h"
  25. #include "Misc.h"
  26. #include "Config.h"
  27. #include "LibHeader.h"
  28. #include "UserInfo.h"
  29. #include "Task.h"
  30. #include "Server.h"
  31. #include "Monitor.h"
  32.  
  33.  
  34.     /*
  35.      *        Static Routines
  36.      */
  37.  
  38. static void myfputs(BPTR file, STRPTR str);
  39. static BOOL myfgets(BPTR file, STRPTR str, ULONG len);
  40. static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd);
  41. static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname);
  42. static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname);
  43. static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
  44.                                  int *retry);
  45. static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output);
  46. static BOOL CheckPassword(STRPTR uid);
  47.  
  48.  
  49.     /*
  50.      *        Support Functions
  51.      */
  52.  
  53. static void __inline myfputs(BPTR file, STRPTR str)
  54. {
  55.     Write(file, str, strlen(str));
  56. }
  57.  
  58.  
  59. static BOOL __inline myfgets(BPTR file, STRPTR str, ULONG len)
  60. {
  61.     LONG readlen;
  62.  
  63.     readlen = Read(file, str, len);
  64.     if (readlen > 1) {
  65.         str[readlen-1] = '\0';
  66.         return(TRUE);
  67.     } else {
  68.         str[0] = '\0';
  69.         return(FALSE);
  70.     }
  71. }
  72.  
  73.  
  74.     /*
  75.      *        Logout and Restore the Previous User
  76.      *
  77.      *        Public Library Function
  78.      *
  79.      *        If there are no users left for the task, a login requester will
  80.      *        appear.
  81.      */
  82.  
  83.  
  84. ULONG __asm __saveds muLogoutA(register __a0 struct TagItem *taglist)
  85. {
  86.     struct muExtOwner *xuser;
  87.     ULONG user;
  88.     struct muPrivUserInfo *info;
  89.     char day[LEN_DATSTRING];
  90.     char date[LEN_DATSTRING];
  91.     char time[LEN_DATSTRING];
  92. #define LASTLOGINSIZE (3*LEN_DATSTRING+2)
  93.     char lastlogin[LASTLOGINSIZE+1];
  94.         /* V39+: use lastlogin[LASTLOGINSIZE] */
  95.     char buffer[256];
  96.     BPTR file, dir, seglist;
  97.     struct DateTime dt;
  98.     struct FileInfoBlock *fib;
  99.     STRPTR args[6];
  100.     struct muTags tags;
  101.     struct Segment *seg;
  102.     BOOL neverloggedin = TRUE;
  103.     int i;
  104.     char *fmt;
  105.     BOOL nobody;
  106.  
  107.     if (!InterpreteTagList(taglist, &tags))
  108.         return(muOWNER_NOBODY);
  109.  
  110.     tags.UserID = tags.Password = NULL;
  111.     tags.NoLog = FALSE;
  112.  
  113.     do {
  114.         if (tags.Global)
  115.             nobody = !PopTaskLevelDetach(tags.Task);
  116.         else
  117.             nobody = !PopTaskDetach(tags.Task);
  118.     } while (tags.All && !nobody);
  119.     user = GetTaskOwner(tags.Task);
  120.     if (nobody && !tags.Quiet)
  121.         if (info = LoginRequest(&tags, FALSE, FALSE)) {
  122.             PushTask(SysBase->ThisTask, &RootExtOwner);
  123.  
  124.             xuser = muUserInfo2ExtOwner(info);
  125.             SetVar("Home", info->Pub.HomeDir, -1, GVF_LOCAL_ONLY);
  126.             if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)) {
  127.                 if (dir = Lock(info->Pub.HomeDir, ACCESS_READ)) {
  128.                     if (Examine(dir, fib) && (fib->fib_DirEntryType > 0)) {
  129.                         if (NameFromLock(dir, buffer, 256))
  130.                             SetCurrentDirName(buffer);
  131.                         dir = CurrentDir(dir);
  132.                     }
  133.                     UnLock(dir);
  134.                 }
  135.                 FreeDosObject(DOS_FIB, fib);
  136.             }
  137.             muFreeUserInfo(info);
  138.  
  139.             if (file = Open(muLastLogin_FileName, MODE_OLDFILE)) {
  140.                 if (FGets(file, lastlogin, LASTLOGINSIZE))
  141.                     neverloggedin = FALSE;
  142.                 Close(file);
  143.             }
  144.             dt.dat_Format = FORMAT_DOS;
  145.             dt.dat_Flags = NULL;
  146.             DateStamp(&dt.dat_Stamp);
  147.             dt.dat_StrDay = day;
  148.             dt.dat_StrDate = date;
  149.             dt.dat_StrTime = time;
  150.             DateToStr(&dt);
  151.             args[0] = day;
  152.             args[1] = date;
  153.             args[2] = time;
  154.             if (file = Open(muLastLogin_FileName, MODE_NEWFILE)) {
  155.                 VFPrintf(file, "%s %s %s\n", (LONG *)args);
  156.                 Close(file);
  157.             }
  158.             if (!neverloggedin) {
  159.                 args[3] = lastlogin;
  160.                 args[4] = "";
  161.                 args[5] = "";
  162.                 for (i = 0; lastlogin[i] && (lastlogin[i] != ' '); i++);
  163.                 if (lastlogin[i]) {
  164.                     lastlogin[i++] = '\0';
  165.                     while (lastlogin[i] == ' ')
  166.                         i++;
  167.                     args[4] = &lastlogin[i];
  168.                     while (lastlogin[i] && (lastlogin[i] != ' '))
  169.                         i++;
  170.                     if (lastlogin[i]) {
  171.                         lastlogin[i++] = '\0';
  172.                         while (lastlogin[i] == ' ')
  173.                             i++;
  174.                         args[5] = &lastlogin[i];
  175.                         while (lastlogin[i] && (lastlogin[i] != ' ') &&
  176.                                  (lastlogin[i] != '\n'))
  177.                             i++;
  178.                         lastlogin[i] = '\0';
  179.                     }
  180.                 }
  181.             }
  182.  
  183.             PopTask(SysBase->ThisTask);
  184.  
  185.             if (neverloggedin)
  186.                 fmt = "Logged in on %s, %s at %s.\n\n"
  187.                         "Never logged in before.";
  188.             else
  189.                 fmt = "Logged in on %s, %s at %s.\n\n"
  190.                         "Last login on %s, %s at %s.";
  191.  
  192.             if (tags.Graphical) {
  193.                 if (muBase->Config.Flags & muCFGF_LastLoginReq)
  194.                     rtEZRequestTags(fmt, "OK", NULL, args,
  195.                                          RTEZ_Flags, EZREQF_CENTERTEXT,
  196.                                          RT_PubScrName, tags.PubScrName,
  197.                                          RT_ReqPos, REQPOS_CENTERSCR,
  198.                                          RT_LockWindow, TRUE,
  199.                                          TAG_DONE);
  200.             } else {
  201.                 FPuts(tags.Output, "\n");
  202.                 VFPrintf(tags.Output, fmt, (LONG *)args);
  203.                 FPuts(tags.Output, "\n");
  204.                 Flush(tags.Output);
  205.             }
  206.  
  207.             if (tags.Global)
  208.                 PushTaskLevel(tags.Task, xuser);
  209.             else
  210.                 PushTask(tags.Task, xuser);
  211.  
  212.             if ((muBase->Config.Flags & muCFGF_Profile) &&
  213.                  (dir = (BPTR)SendServerPacket(muSAction_ConfigDirLock, NULL,
  214.                                                          NULL, NULL, NULL))) {
  215.                 dir = CurrentDir(dir);
  216.                 if (file = Lock(muProfile_FileName, ACCESS_READ)) {
  217.                     Forbid();
  218.                     if (seg = FindSegment("Execute", NULL, NULL))
  219.                         seg->seg_UC++;
  220.                     Permit();
  221.                     if (seg)
  222.                         seglist = seg->seg_Seg;
  223.                     else
  224.                         seglist = NewLoadSeg("C:Execute", NULL);
  225.                     if (seglist) {
  226.                         RunCommand(seglist, 4000, muProfile_FileName "\n",
  227.                                       strlen(muProfile_FileName "\n"));
  228.                         if (!seg)
  229.                             UnLoadSeg(seglist);
  230.                     }
  231.                     if (seg) {
  232.                         Forbid();
  233.                         seg->seg_UC--;
  234.                         Permit();
  235.                     }
  236.                     UnLock(file);
  237.                 }
  238.                 UnLock(CurrentDir(dir));
  239.             }
  240.             user = muExtOwner2ULONG(xuser);
  241.             muFreeExtOwner(xuser);
  242.         } else
  243.             Die(NULL, AN_Unknown | AG_BadParm);
  244.  
  245.     return(user);
  246. }
  247.  
  248.  
  249.     /*
  250.      *        Login to the System and Add the User to the Task
  251.      *
  252.      *        Public Library Function
  253.      */
  254.  
  255.  
  256. ULONG __asm __saveds muLoginA(register __a0 struct TagItem *taglist)
  257. {
  258.     struct muExtOwner *xuser;
  259.     struct muPrivUserInfo *info;
  260.     struct muTags tags;
  261.     BOOL res;
  262.  
  263.     if (!InterpreteTagList(taglist, &tags) || (tags.Password && !tags.UserID))
  264.         return(muOWNER_NOBODY);
  265.  
  266.     xuser = GetTaskExtOwner(SysBase->ThisTask);
  267.     if (!tags.Own)
  268.         if (info = LoginRequest(&tags, TRUE, muGetRelationshipA(xuser, NULL, NULL) & muRelF_ROOT_UID)) {
  269.             muFreeExtOwner(xuser);
  270.             xuser = muUserInfo2ExtOwner(info);
  271.             muFreeUserInfo(info);
  272.         } else {
  273.             muFreeExtOwner(xuser);
  274.             return(muOWNER_NOBODY);
  275.         }
  276.  
  277.     if (tags.Global)
  278.         res = PushTaskLevel(tags.Task, xuser);
  279.     else
  280.         res = PushTask(tags.Task, xuser);
  281.     muFreeExtOwner(xuser);
  282.  
  283.     return(GetTaskOwner(tags.Task));
  284. }
  285.  
  286.  
  287.     /*
  288.      *        Request the User for a Login
  289.      */
  290.  
  291. static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd)
  292. {
  293.     BOOL ret;
  294.     char version[8];
  295.     char hostname[32];
  296.     char uidbuf[muUSERIDSIZE];
  297.     char pwdbuf[muPASSWORDSIZE];
  298.     STRPTR userid, password;
  299.     struct muPrivUserInfo *info = NULL;
  300.     int retry = 0, i;
  301.  
  302.     if (GetVar("Kickstart", version, 8, GVF_GLOBAL_ONLY) == -1)
  303.         strcpy(version, "?");
  304.     if (GetVar("HostName", hostname, 32, GVF_GLOBAL_ONLY) == -1)
  305.         strcpy(hostname, "?");
  306.     else {
  307.         for (i = 0; hostname[i] && (hostname[i] != '.'); i++);
  308.         if (hostname[i] == '.')
  309.             hostname[i] = '\0';
  310.     }
  311.  
  312.     do {
  313.         if (tags->UserID)
  314.             userid = tags->UserID;
  315.         else {
  316.             userid = uidbuf;
  317.             do {
  318.                 memset(uidbuf, '\0', sizeof(uidbuf));
  319.                 if (tags->Graphical)
  320.                     ret = GetUserIDGUI(uidbuf, version, hostname, tags->PubScrName);
  321.                 else
  322.                     ret = GetUserIDCon(uidbuf, version, hostname, tags->Input,
  323.                                              tags->Output, &retry);
  324.                 if (!ret && failallowed)
  325.                     return(NULL);
  326.             } while (!ret);
  327.         }
  328.         if (tags->Password)
  329.             password = tags->Password;
  330.         else {
  331.             password = pwdbuf;
  332.             memset(pwdbuf, '\0', sizeof(pwdbuf));
  333.             if (!nopasswd && CheckPassword(userid)) {
  334.                 if (tags->Graphical)
  335.                     ret = GetPasswordGUI(pwdbuf, tags->PubScrName);
  336.                 else
  337.                     ret = GetPasswordCon(pwdbuf, tags->Input, tags->Output);
  338.                 if (!ret)
  339.                     if (failallowed)
  340.                         return(NULL);
  341.                     else
  342.                         password = NULL;
  343.             }
  344.         }
  345.         if (userid && password) {
  346.             info = (struct muPrivUserInfo *)SendServerPacket(muSAction_CheckUser, (LONG)userid,
  347.                                                                              (LONG)password, (LONG)nopasswd,
  348.                                                                              (LONG)tags->NoLog);
  349.             memset(pwdbuf, '\0', sizeof(pwdbuf));
  350.             if (!info)
  351.                 if (failallowed)
  352.                     return(NULL);
  353.                 else if (tags->Graphical)
  354.                     rtEZRequestTags("Login incorrect", "OK", NULL, NULL,
  355.                                          RTEZ_Flags, EZREQF_CENTERTEXT,
  356.                                          RT_PubScrName, tags->PubScrName,
  357.                                          RT_ReqPos, REQPOS_CENTERSCR,
  358.                                          RT_LockWindow, TRUE,
  359.                                          TAG_DONE);
  360.                 else
  361.                     myfputs(tags->Output, "\n     Login incorrect!!\n");
  362.         }
  363.     } while (!info);
  364.     return(info);
  365. }
  366.  
  367.  
  368.     /*
  369.      *        Ask the User for his UserID (Graphical User Interface version)
  370.      */
  371.  
  372. static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname)
  373. {
  374.     STRPTR args[2];
  375.  
  376.     args[0] = version;
  377.     args[1] = hostname;
  378.     return((BOOL)rtGetString(userid, muUSERIDSIZE-1, "MultiUser Login Request",
  379.                                      NULL, RTGS_TextFmt, "AmigaOS %s at %s\n\n"
  380.                                                                 "Enter your Login ID",
  381.                                              RTGS_TextFmtArgs, args,
  382.                                              RTGS_Flags, GSREQF_CENTERTEXT,
  383.                                              RT_PubScrName, scrname,
  384.                                              RT_ReqPos, REQPOS_CENTERSCR,
  385.                                              RT_LockWindow, TRUE,
  386.                                              TAG_DONE));
  387. }
  388.  
  389.  
  390.     /*
  391.      *        Ask the User for his Password (Graphical User Interface version)
  392.      */
  393.  
  394. static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname)
  395. {
  396.     return((BOOL)rtGetString(password, muPASSWORDSIZE-1,
  397.                                      "MultiUser Login Request", NULL,
  398.                                      RTGS_TextFmt, "Enter your Password",
  399.                                      RTGS_Invisible, TRUE,
  400.                                      RTGS_AllowEmpty, TRUE,
  401.                                      RTGS_Flags, GSREQF_CENTERTEXT,
  402.                                      RT_PubScrName, scrname,
  403.                                      RT_ReqPos, REQPOS_CENTERSCR,
  404.                                      RT_LockWindow, TRUE,
  405.                                      TAG_DONE));
  406. }
  407.  
  408.  
  409.     /*
  410.      *        Ask the User for his UserID (Standard Console I/O version)
  411.      */
  412.  
  413. static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
  414.                                  int *retry)
  415. {
  416.     STRPTR args[2];
  417.     BOOL ret;
  418.  
  419.     args[0] = version;
  420.     args[1] = hostname;
  421.     if (!*retry) {
  422.         VFPrintf(output, "H\n\n\n     AmigaOS %s at %s\n",
  423.                     (LONG *)args);
  424.         Flush(output);
  425.     }
  426.     myfputs(output, "\n\nLogin    : ");
  427.     ret = myfgets(input, userid, muUSERIDSIZE);
  428.     if (ret)
  429.         *retry = (*retry+1) % 4;
  430.     else
  431.         *retry = 0;
  432.     return(ret);
  433. }
  434.  
  435.  
  436.     /*
  437.      *        Ask the User for his Password (Standard Console I/O version)
  438.      */
  439.  
  440. static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output)
  441. {
  442.     BOOL done;
  443.     ULONG len;
  444.     char buffer;
  445.  
  446.     myfputs(output, "Password : ");
  447.     done = FALSE;
  448.     len = 0;
  449.     SetMode(input, 1);
  450.     do {
  451.         Read(input, &buffer, 1);
  452.         switch(buffer) {
  453.             case    '\b':
  454.                 if (len) {
  455.                     FPutC(output, '\b');
  456.                     Flush(output);
  457.                     len--;
  458.                 }
  459.                 break;
  460.  
  461.             case    '\n':
  462.             case    '\r':
  463.                 done = TRUE;
  464.                 break;
  465.  
  466.             default:
  467.                 if ((len < muPASSWORDSIZE-1) && ((buffer & 0x7f) > 31)
  468.                      && (buffer != 127)) {
  469.                     FPutC(output, ' ');
  470.                     password[len++] = buffer;
  471.                 } else
  472.                     FPutC(output, 7);
  473.                 Flush(output);
  474.                 break;
  475.         }
  476.     } while (!done);
  477.     password[len] = '\0';
  478.     SetMode(input, 0);
  479.     myfputs(output, "\n");
  480.     return(TRUE);
  481. }
  482.  
  483.  
  484.     /*
  485.      *        Check whether a User has a Password or not
  486.      */
  487.  
  488. static BOOL CheckPassword(STRPTR userid)
  489. {
  490.     struct muPrivUserInfo *info;
  491.     BOOL pwd = TRUE;
  492.  
  493.     if (info = muAllocUserInfo()) {
  494.         strncpy(info->Pub.UserID, userid, muUSERIDSIZE-1);
  495.         info->Pub.UserID[muUSERIDSIZE-1] = '\0';
  496.         if (SendServerPacket(muSAction_GetUserInfo, (LONG)info, muKeyType_UserID, NULL, NULL))
  497.             pwd = info->Password;
  498.         muFreeUserInfo(info);
  499.     }
  500.     return(pwd);
  501. }
  502.